package com.couchbase.loadgen.cluster;
import java.util.List;
import org.restlet.Component;
import org.restlet.data.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.couchbase.loadgen.Config;
import com.couchbase.loadgen.client.Loadgen;
import com.couchbase.loadgen.client.StatsManager;
import com.couchbase.loadgen.measurements.Measurements;
import com.couchbase.loadgen.rest.ClusterRest;
import com.sun.enterprise.ee.cms.core.CallBack;
import com.sun.enterprise.ee.cms.core.FailureNotificationSignal;
import com.sun.enterprise.ee.cms.core.FailureSuspectedSignal;
import com.sun.enterprise.ee.cms.core.GMSException;
import com.sun.enterprise.ee.cms.core.GMSFactory;
import com.sun.enterprise.ee.cms.core.GMSMember;
import com.sun.enterprise.ee.cms.core.GroupHandle;
import com.sun.enterprise.ee.cms.core.GroupManagementService;
import com.sun.enterprise.ee.cms.core.JoinNotificationSignal;
import com.sun.enterprise.ee.cms.core.MessageSignal;
import com.sun.enterprise.ee.cms.core.PlannedShutdownSignal;
import com.sun.enterprise.ee.cms.core.Signal;
import com.sun.enterprise.ee.cms.core.SignalAcquireException;
import com.sun.enterprise.ee.cms.core.SignalReleaseException;
import com.sun.enterprise.ee.cms.impl.client.FailureNotificationActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.FailureSuspectedActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.JoinNotificationActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.MessageActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.PlannedShutdownActionFactoryImpl;
public class ClusterManager implements CallBack {
private static final Logger LOG = LoggerFactory.getLogger(ClusterManager.class);
public static final String GROUP_NAME = "loadgenerator";
private static ClusterManager cm = null;
private GroupManagementService gms;
private Loadgen lg;
private StatsManager sm;
private int nodesrunning;
private boolean running;
final Object waitLock = new Object();
private ClusterManager() {
nodesrunning = 0;
running = false;
initNode();
joinNodeToCluster();
}
private void initNode() {
String server = "server" + System.currentTimeMillis();
gms = (GroupManagementService) GMSFactory.startGMSModule(server, GROUP_NAME, GroupManagementService.MemberType.CORE, null);
}
private void joinNodeToCluster() {
try {
gms.join();
registerForGroupEvents(gms);
} catch (GMSException e) {
e.printStackTrace();
}
}
public static ClusterManager getManager() {
if (cm == null)
cm = new ClusterManager();
return cm;
}
private void registerForGroupEvents(GroupManagementService gms) {
gms.addActionFactory(new JoinNotificationActionFactoryImpl(this));
gms.addActionFactory(new FailureSuspectedActionFactoryImpl(this));
gms.addActionFactory(new FailureNotificationActionFactoryImpl(this));
gms.addActionFactory(new PlannedShutdownActionFactoryImpl(this));
gms.addActionFactory(new MessageActionFactoryImpl(this), GROUP_NAME);
}
public void processNotification(Signal signal) {
try {
signal.acquire();
if (signal instanceof MessageSignal) {
Message message = Message.decode(((MessageSignal) signal).getMessage());
if (message.getOpcode() == Message.OP_START) {
startLoadGeneration();
} else if (message.getOpcode() == Message.OP_FINISH) {
nodesrunning--;
} else if (message.getOpcode() == Message.OP_STOP) {
stopLoadGeneration();
} else if (message.getOpcode() == Message.OP_CONFIG) {
Config.getConfig().setConfig(new String(message.getBody()));
} else if (message.getOpcode() == Message.OP_STATS) {
try {
Measurements.getMeasurements().addMeasurement(new String(message.getBody()));
} catch (Exception e) {
e.printStackTrace();
System.out.println("Body: " + new String(message.getBody()));
}
}
} else {
if (signal instanceof JoinNotificationSignal) {
System.out.println("Joining node " + signal.getMemberToken());
} else if (signal instanceof FailureSuspectedSignal) {
System.out.println("Failure Suspected " + signal.getMemberToken());
} else if (signal instanceof FailureNotificationSignal) {
System.out.println("Failure notification " + signal.getMemberToken());
} else if (signal instanceof PlannedShutdownSignal) {
System.out.println("Planned shutdown " + signal.getMemberToken());
} else {
System.out.println("Recieved unknown signal " + signal.toString());
}
}
signal.release();
} catch (SignalAcquireException e) {
e.printStackTrace();
} catch (SignalReleaseException e) {
e.printStackTrace();
}
}
public String getServerList() {
GroupHandle gh = gms.getGroupHandle();
String members = "";
List<GMSMember> m = gh.getCurrentView();
for (int i = 0; i < m.size(); i++) {
members = members + m.get(i).getMemberToken() + "\n";
}
return members;
}
public int getClusterSize() {
return gms.getGroupHandle().getCurrentView().size();
}
public void sendMessage(Message message) throws GMSException {
GroupHandle gh = gms.getGroupHandle();
gh.sendMessage(GROUP_NAME, message.encode());
}
public boolean getClusterStatus() {
if (nodesrunning == 0)
return false;
return true;
}
public boolean startLoadGeneration() {
if (nodesrunning == 0) {
nodesrunning = gms.getGroupHandle().getCurrentView().size();
running = true;
lg = new Loadgen();
sm = new StatsManager();
lg.start();
sm.start();
return true;
}
LOG.error("Couldn't start load generation: Already running");
return false;
}
public void finishedLoadGeneration() {
if (running) {
try {
Message message = new Message();
message.setOpcode(Message.OP_FINISH);
sendMessage(message);
sm.done();
nodesrunning--;
running = false;
} catch (GMSException e) {
LOG.error("Couldn't send finish message");
}
}
}
public void stopLoadGeneration() {
if (running) {
lg.terminate();
finishedLoadGeneration();
}
}
public static void main(String args[]) {
ClusterManager.getManager();
try {
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
component.getDefaultHost().attach("/cluster", new ClusterRest());
component.start();
} catch (Exception e) {
}
}
}